﻿using System;
using System.Configuration;
using System.Globalization;
using System.Resources;
using System.Threading;
using System.Windows.Forms;
using Timer = System.Windows.Forms.Timer;

namespace OSController
{
    public partial class MainForm : Form
    {
        #region Props&Fields
        private readonly Controller _controller;
        private readonly ResourceManager _resManager;

        private string CultureSetting
        {
            get { return ConfigurationManager.AppSettings["Culture"]; }
        }

        private string InfoFormat
        {
            get
            {
                string val = _resManager.GetString("InfoMessage");
                if (String.IsNullOrWhiteSpace(val))
                    return "<{0}> will be applied <{1}> secs later.";
                return val;
            }
        }

        private int TimeOut { get; set; }
        #endregion

        #region Methods
        public MainForm()
        {
            SetCulture();
            InitializeComponent();
            _resManager = new ResourceManager("OSController.ManRes", GetType().Assembly);
            cbActionJN.SelectedIndex = 0;
            cb_Action.SelectedIndex = 0;
            var roundedNow = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, DateTime.Now.Hour,
                                          DateTime.Now.Minute, 0);
            datePicker.Value = roundedNow;
            datePicker.MinDate = roundedNow;
            datePicker.MaxDate = DateTime.Now.AddDays(7);
            SetPanelVisibilities();
            _controller = new Controller(this);
            foreach (Control c in Controls)
                c.KeyDown += OnGenericKeyDown;
        }

        private void SetCulture()
        {
            string c = CultureSetting;
            if (String.IsNullOrWhiteSpace(c))
                return;
            Thread.CurrentThread.CurrentUICulture = new CultureInfo(c);
        }

        private void SetAction()
        {
            switch (cb_Action.SelectedIndex)
            {
                case 0:
                    _controller.Action = ActionType.MonitorOff;
                    break;
                case 1:
                    _controller.Action = ActionType.Lock;
                    break;
                case 2:
                    _controller.Action = ActionType.LogOff;
                    break;
                case 3:
                    _controller.Action = ActionType.Sleep;
                    break;
                case 4:
                    _controller.Action = ActionType.Hibernate;
                    break;
                case 5:
                    _controller.Action = ActionType.Restart;
                    break;
                case 6:
                    _controller.Action = ActionType.ShutDown;
                    break;
            }
        }

        private void SetPanelVisibilities()
        {
            if (rb_Timer.Checked)
            {
                timerPanel.Enabled = true;
                datePanel.Enabled = false;
            }
            else if (rb_OnTime.Checked)
            {
                timerPanel.Enabled = false;
                datePanel.Enabled = true;
            }
            else
            {
                timerPanel.Enabled = false;
                datePanel.Enabled = false;
            }
        }
        #endregion

        #region Events
        private void bt_Apply_Click(object sender, EventArgs e)
        {
            SetAction();
            if (rb_Timer.Checked)
            {
                TimeOut = cb_Unit.SelectedIndex < 1 ? cb_Timer.Number * 60000 : cb_Timer.Number * 1000;
                if (TimeOut <= 0)
                    return;
                panel_Info.Show();
                progressBar.Maximum = TimeOut;
                timer.Start();
            }
            else if (rb_OnTime.Checked)
            {
                TimeOut = (int)datePicker.Value.Subtract(DateTime.Now).TotalSeconds * 1000;
                if (TimeOut <= 0)
                    return;
                panel_Info.Show();
                progressBar.Maximum = TimeOut;
                timer.Start();
            }
            bt_Apply.Enabled = false;
        }

        private void rb_Timer_CheckedChanged(object sender, EventArgs e)
        {
            SetPanelVisibilities();
        }

        private void rb_OnTime_CheckedChanged(object sender, EventArgs e)
        {
            SetPanelVisibilities();
        }

        private void bt_Cancel_Click(object sender, EventArgs e)
        {
            timer.Stop();
            progressBar.Value = 0;
            panel_Info.Hide();
            bt_Apply.Enabled = true;
        }

        private void OnGenericKeyDown(object sender, KeyEventArgs args)
        {
            switch (args.KeyCode)
            {
                case Keys.Enter:
                    bt_Apply.PerformClick();
                    break;
                case Keys.Escape:
                    bt_Cancel.PerformClick();
                    break;
            }
        }

        private void btApplyJN_Click(object sender, EventArgs e)
        {
            switch (cbActionJN.SelectedIndex)
            {
                case 0:
                    _controller.Action = ActionType.MonitorOff;
                    break;
                case 1:
                    _controller.Action = ActionType.Lock;
                    break;
                case 2:
                    _controller.Action = ActionType.LogOff;
                    break;
                case 3:
                    _controller.Action = ActionType.Sleep;
                    break;
                case 4:
                    _controller.Action = ActionType.Hibernate;
                    break;
                case 5:
                    _controller.Action = ActionType.Restart;
                    break;
                case 6:
                    _controller.Action = ActionType.ShutDown;
                    break;
            }
            _controller.ApplyAction();
        }

        private void timer_Tick(object sender, EventArgs e)
        {
            if (!(sender is Timer))
                return;
            lbl_Info.Text = String.Format(InfoFormat, cb_Action.SelectedItem, TimeOut / 1000);
            var tmr = sender as Timer;
            TimeOut -= tmr.Interval;
            progressBar.Value += tmr.Interval;
            if (TimeOut == 0)
            {
                tmr.Stop();
                _controller.ApplyAction();
                panel_Info.Hide();
                progressBar.Value = 0;
                bt_Apply.Enabled = true;
            }
        }
        #endregion
    }
}